/*
 * Copyright (c) 2023 iQi.Co.Ltd. All rights reserved.
 */
 
using System.Collections.Generic;
using NetProtocol.POD;
using NetProtocol.Enum;
using IQIGame.Onigao.Game;
using IQIGame.Onigao.GamePlay;
using IQIGame.Onigao.Framework;
using System.Threading.Tasks;
using System;

namespace NetProtocol.Server {
	/// <summary>
	/// 主城模块
	/// module : mainCity
	/// </summary>
	public interface SNetMainCity : INetServerModule {
		Dictionary<int, MessageHandler> INetServerModule.GetModuleFunction()
        {	
            return new()
            {
                { NetMessageId.mainCity_uploadPlayerPos, (session, data) =>
		            {
#if ENABLE_NET_LOG || UNITY_EDITOR
						NetProtocolHelper.ServerLog(NetMessageId.mainCity_uploadPlayerPos, "Recv->" + data.ToString());
#endif
		                UploadPlayerPosRequest _data = (UploadPlayerPosRequest)data;
		                CS_uploadPlayerPos(session, _data.regionCid, _data.x, _data.y, _data.z);
		                return VoidMessageResult.Instance;
		            } 
            	},
                { NetMessageId.mainCity_requestExeService, (session, data) =>
		            {
#if ENABLE_NET_LOG || UNITY_EDITOR
						NetProtocolHelper.ServerLog(NetMessageId.mainCity_requestExeService, "Recv->" + data.ToString());
#endif
		                RequestExeServiceRequest _data = (RequestExeServiceRequest)data;
						return CS_requestExeService(session, _data.npcId, _data.index);
		            } 
            	},
            };
        }
        
        Dictionary<int, Func<IReceiveMessage>> INetServerModule.GetModuleRequest() 
        {
	        return new ()
	        {
	        	{NetMessageId.mainCity_uploadPlayerPos, ()=> new UploadPlayerPosRequest()},
	        	{NetMessageId.mainCity_requestExeService, ()=> new RequestExeServiceRequest()},
	        };
	    }
        
#region Server-side Interface
		/// <summary>
        /// 同步玩家坐标
        /// </summary>
    	protected bool CS_uploadPlayerPos(ISession session, int regionCid, float x, float y, float z);
		/// <summary>
        /// 请求执行服务
        /// </summary>
	    protected RequestExeServiceResult CS_requestExeService(ISession session, int npcId, int index);
#endregion
#region Client-side Interface
		/// <summary>
        ///  通知天气更新
        /// </summary>
		public bool SC_notifyWeather(ISession session, int weatherCid){
	        return NetProtocolHelper.SendMessage(session, new NotifyWeather(weatherCid));
	    }
	    public void SC_notifyWeather_Broadcast(List<ISession> sessions, int weatherCid){
	        NetProtocolHelper.BroadcastMessage(sessions, new NotifyWeather(weatherCid));
	    }
		/// <summary>
        ///  执行服务结果
        /// </summary>
        public RequestExeServiceResult SC_requestExeServiceResult(Task<RequestExeServiceResult> future){return new RequestExeServiceResult(future);}
        public RequestExeServiceResult SC_requestExeServiceResult(int code, int regionCid, MainCityNpcPOD npcData){return new RequestExeServiceResult(code, regionCid, npcData);}
        public RequestExeServiceResult SC_requestExeServiceResult(int code){return new RequestExeServiceResult(code);}
		/// <summary>
        ///  通知npc更新
        /// </summary>
		public bool SC_notifyNpcUpdate(ISession session, int regionCid, MainCityNpcPOD npcData){
	        return NetProtocolHelper.SendMessage(session, new NotifyNpcUpdate(regionCid, npcData));
	    }
	    public void SC_notifyNpcUpdate_Broadcast(List<ISession> sessions, int regionCid, MainCityNpcPOD npcData){
	        NetProtocolHelper.BroadcastMessage(sessions, new NotifyNpcUpdate(regionCid, npcData));
	    }
		/// <summary>
        ///  通知npc掉落
        /// </summary>
		public bool SC_notifyNpcDrop(ISession session, int regionCid, int npcId, List<ItemShowPOD> awards){
	        return NetProtocolHelper.SendMessage(session, new NotifyNpcDrop(regionCid, npcId, awards));
	    }
	    public void SC_notifyNpcDrop_Broadcast(List<ISession> sessions, int regionCid, int npcId, List<ItemShowPOD> awards){
	        NetProtocolHelper.BroadcastMessage(sessions, new NotifyNpcDrop(regionCid, npcId, awards));
	    }
		/// <summary>
        ///  通知执行
        /// </summary>
		public bool SC_notifyNpcExecution(ISession session, int regionCid, int npcId, int excutionId){
	        return NetProtocolHelper.SendMessage(session, new NotifyNpcExecution(regionCid, npcId, excutionId));
	    }
	    public void SC_notifyNpcExecution_Broadcast(List<ISession> sessions, int regionCid, int npcId, int excutionId){
	        NetProtocolHelper.BroadcastMessage(sessions, new NotifyNpcExecution(regionCid, npcId, excutionId));
	    }
#endregion

#region Messages
	public class NotifyWeather : MessageNotify {
		private int weatherCid;
		public NotifyWeather(int weatherCid) {
		    this.weatherCid = weatherCid;
		}
		public override int GetMessageId() {return NetMessageId.mainCity_notifyWeather;}
		public override SendPackage ToPackage() {
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.mainCity_notifyWeather;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(weatherCid);
			return si_p;
		}
		public override string ToString() {
			return "MainCity.SC_notifyWeather { "
			+ "weatherCid="
			+ weatherCid
			+" }";
		}
	}
	public class RequestExeServiceResult : MessageResult {
	    private int regionCid;
	    private MainCityNpcPOD npcData;
	    public RequestExeServiceResult(Task<RequestExeServiceResult> future): base(future) { }
		public RequestExeServiceResult(int code): base(code) { }
		public new RequestExeServiceResult SetDelayCall(Action delayCall) { base.SetDelayCall(delayCall); return this; }
	    internal RequestExeServiceResult(int code, int regionCid, MainCityNpcPOD npcData){
	        this.code = code;
	        this.regionCid = regionCid;
	        this.npcData = npcData;
	    }
        public override MessageResult GetFutureResult(Task task) { return ((Task<RequestExeServiceResult>)task).Result; }
		public override int GetMessageId() {return NetMessageId.mainCity_requestExeServiceResult;}
		public override SendPackage ToPackage() {
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.mainCity_requestExeServiceResult;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(code);
			_out.Write_int(regionCid);
			_out.Write_pod(npcData);
			return si_p;
		}
		public override string ToString() {
    		return "MainCity.SC_requestExeServiceResult { "
			+ "code="
			+ code
			+ ", regionCid="
			+ regionCid
			+ ", npcData="
			+ npcData
			+" }";
		}
	}
	public class NotifyNpcUpdate : MessageNotify {
		private int regionCid;
		private MainCityNpcPOD npcData;
		public NotifyNpcUpdate(int regionCid, MainCityNpcPOD npcData) {
		    this.regionCid = regionCid;
		    this.npcData = npcData;
		}
		public override int GetMessageId() {return NetMessageId.mainCity_notifyNpcUpdate;}
		public override SendPackage ToPackage() {
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.mainCity_notifyNpcUpdate;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(regionCid);
			_out.Write_pod(npcData);
			return si_p;
		}
		public override string ToString() {
			return "MainCity.SC_notifyNpcUpdate { "
			+ "regionCid="
			+ regionCid
			+ ", npcData="
			+ npcData
			+" }";
		}
	}
	public class NotifyNpcDrop : MessageNotify {
		private int regionCid;
		private int npcId;
		private List<ItemShowPOD> awards;
		public NotifyNpcDrop(int regionCid, int npcId, List<ItemShowPOD> awards) {
		    this.regionCid = regionCid;
		    this.npcId = npcId;
		    this.awards = awards == null ? null : new (awards);
		}
		public override int GetMessageId() {return NetMessageId.mainCity_notifyNpcDrop;}
		public override SendPackage ToPackage() {
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.mainCity_notifyNpcDrop;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(regionCid);
			_out.Write_int(npcId);
			_out.Write_list_pod(awards);
			return si_p;
		}
		public override string ToString() {
			return "MainCity.SC_notifyNpcDrop { "
			+ "regionCid="
			+ regionCid
			+ ", npcId="
			+ npcId
			+ ", awards="
			+ awards.ToString<ItemShowPOD>()
			+" }";
		}
	}
	public class NotifyNpcExecution : MessageNotify {
		private int regionCid;
		private int npcId;
		private int excutionId;
		public NotifyNpcExecution(int regionCid, int npcId, int excutionId) {
		    this.regionCid = regionCid;
		    this.npcId = npcId;
		    this.excutionId = excutionId;
		}
		public override int GetMessageId() {return NetMessageId.mainCity_notifyNpcExecution;}
		public override SendPackage ToPackage() {
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.mainCity_notifyNpcExecution;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(regionCid);
			_out.Write_int(npcId);
			_out.Write_int(excutionId);
			return si_p;
		}
		public override string ToString() {
			return "MainCity.SC_notifyNpcExecution { "
			+ "regionCid="
			+ regionCid
			+ ", npcId="
			+ npcId
			+ ", excutionId="
			+ excutionId
			+" }";
		}
	}
	private class UploadPlayerPosRequest : IReceiveMessage
    {
		internal int regionCid;
		internal float x;
		internal float y;
		internal float z;
        public void FromPackage(ReceivePackage package)
		{
			SInputStream _in = package.InputStream;
            regionCid = _in.HasRemaining() ? _in.Read_int() : default;
            x = _in.HasRemaining() ? _in.Read_float() : default;
            y = _in.HasRemaining() ? _in.Read_float() : default;
            z = _in.HasRemaining() ? _in.Read_float() : default;
		}
        public int GetMessageId() { return NetMessageId.mainCity_uploadPlayerPos; }
        public override string ToString()
        {
            return "MainCity.uploadPlayerPos"+ ", regionCid="+ regionCid+ ", x="+ x+ ", y="+ y+ ", z="+ z;
        }
    }
	private class RequestExeServiceRequest : IReceiveMessage
    {
		internal int npcId;
		internal int index;
        public void FromPackage(ReceivePackage package)
		{
			SInputStream _in = package.InputStream;
            npcId = _in.HasRemaining() ? _in.Read_int() : default;
            index = _in.HasRemaining() ? _in.Read_int() : default;
		}
        public int GetMessageId() { return NetMessageId.mainCity_requestExeService; }
        public override string ToString()
        {
            return "MainCity.requestExeService"+ ", npcId="+ npcId+ ", index="+ index;
        }
    }
	}
#endregion
}